from multiprocessing import Process
from random import randint
from threading import Thread
from time import time, sleep

counter = 0

def download_task(name):
    print("开始下载%s..." % name)
    time_to_download = randint(5, 10)
    sleep(time_to_download)
    print("%s下载完成，耗时%d秒" % (name, time_to_download))


def main():
    stat = time()
    download_task("Python从入门到入院.pdf")
    download_task("Java21天入門.doc")
    end = time()
    print("总共耗费%d秒" % (end - stat))

def main1():
    stat = time()
    ## Process是多进程， 多线程要用Thread
    Process(target=download_task, args=("多线程下载1",)).start()
    process = Process(target=download_task, args=("团长",))
    process.start()
    end = time()

    ##而join方法表示等待进程执行结束
    process.join()
    print("总共下载耗时%d" % (end - stat))

#这种写法是错误的， 子进程复制了父进程及其所有的数据结构，每个子进程有自己独立的内存空间，这也就意味着两个子进程中各有一个counter变量
#应当使用multiprocessing模块中的Queue
def sub_task(string):
    global counter
    while counter < 10:

        ## 当设置flush=True时，Python会在执行print函数后立即将内部缓冲区的内容刷新到输出流，确保所有的输出都被立即写入，而不是等到缓冲区满了或者程序结束。这在以下情况下特别有用：
         # 1.当你需要确保日志或错误消息立即被写入，而不是在程序崩溃后丢失时。
         # 2.当你在交互式环境中工作，需要立即看到输出结果时。
         # 3.当你在写一个需要实时输出信息的程序，比如进度条，你希望用户能够实时看到进度更新。
        print(string, end='###\n', flush=True)
        counter += 1
        sleep(0.01)


def thread_test():
    start = time()
    thread1 = Thread(target=download_task, args=("多线程测试1",))
    thread2 = Thread(target=download_task, args=("多线程测试2",))

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()
    end = time()

    print("总共耗费了%d秒" % (end - start))


class DownloadTask(Thread):
    def __init__(self, filename):
        super().__init__()
        self._filename = filename

    def run(self):
        print("开始下载%s...." % self._filename)
        time_to_download = randint(5, 10)
        sleep(time_to_download)
        print("%s下载完成！耗时%d秒" % (self._filename, time_to_download))






if __name__ == '__main__':
    #=== Process多进程
    Process(target=sub_task, args=("Ping",)).start()
    Process(target=sub_task, args=("Pong",)).start()

    #main1()

    #=== Process是多进程， 多线程要用Thread
    thread_test()

    ##继承Thread类的方式来创建自定义的线程类
    start = time()
    task = DownloadTask("测试1.avi")
    task2 = DownloadTask("测试2.avi")

    task.start()
    task2.start()
    task.join()
    task2.join()

    end = time()

    print("总耗时：%d" % (end - start))
